﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Configuration;
using System.Data;
using System.Collections;
using System.IO;
using System.IO.Compression;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;

namespace Utils.DC.Web.UI
{
    /// <summary>
    /// Cac ham dung de lam viec voi cac chuc nang cua web nhu caching
    /// Author: Dao Xuan Trung
    /// Date Modified: 20/01/2010
    /// </summary>
    public class WebUtility
    {
        #region Cac Ham Lam Viec Voi Cache

        /// <summary>
        /// Ham Remove Cache
        /// </summary>
        /// <param name="key">Key cua cache</param>
        public static void RemoveCache(String key)
        {
            HttpRuntime.Cache.Remove(key);
        }

        /// <summary>
        /// Ham dung de them cache co cau hinh thoi gian cache
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="cacheTime"></param>
        public static void InsertCache(String key, object value, DateTime cacheTime)
        {
            HttpRuntime.Cache.Insert(key,value,null,cacheTime,Cache.NoSlidingExpiration);
        }

        /// <summary>
        /// Ham dung de them cache voi thoi gian cache mac dinh, dat trong webconfig
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void InsertCache(String key, object value)
        {
            int cacheTime = Convert.ToInt32(ConfigurationManager.AppSettings["DefaultCacheTime"]);
            HttpRuntime.Cache.Insert(key,value,null,DateTime.Now.AddSeconds(cacheTime),Cache.NoSlidingExpiration);
        }

        /// <summary>
        /// Ham dung de lay ve gia tri cua cache
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetCacheObject(String key)
        {
            return HttpRuntime.Cache.Get(key);
        }
        #endregion

        #region Cac Ham Thao Tac Voi Du Lieu 

        /// <summary>
        /// Ham lay ve duong dan cua 1 trang (tim cac trang cha cua no roi ghep chuoi tao thanh duong dan )
        /// </summary>
        /// <param name="pageID">ID cua trang hien tai</param>
        /// <param name="dtPageList">Danh sach cac trang</param>
        /// <param name="isFirst">Biến dùng để xác định đây có phải là vòng đệ qui đầu tiên không? nếu là đầu tiên thì check có phải là trang admin không để add URL path /admin/ vào</param>
        /// <returns>Chuoi Duong dan</returns>
        public static string GetParentUrl(int pageID, DataTable dtPageList)
        {
            bool isLast = false;
            //Lay ve thong tin cua trang hien tai
            if (pageID != 0)
            {
                DataRow row = dtPageList.Select("FunctionPageID = " + pageID)[0];
                string url = row["FunctionPageAlias"].ToString().Trim() + "/";

                //Lay ve trang cha cua trang hien tai 
                //(trang cha co the null neu day la trang co trang cha la trang chuc nang (functionPage) )
                //Neu ko phai la trang goc thi tiep tuc lay trang cha
                if (row["ParentID"] != null && row["ParentID"].ToString().Trim() != "")
                {
                    int? ParentID = Convert.ToInt32(row["ParentID"]);
                    //DataRow parentRows = dtPageList.Select("FunctionPageID = " + ParentID)[0];
                    url = GetParentUrl(ParentID.Value, dtPageList) + url;
                }
                else
                {
                    isLast = true;
                }

                //Nếu là trang admin
                if (isLast)
                {
                    if (Convert.ToBoolean(row["IsAdmin"]))
                        url = "/admin/" + url;
                    else
                        url = "/" + url;
                }

                //Sau khi lay den trang goc thi tra ve url
                return url;
            }
            else
            {
                return "";
            }
        }

        #endregion

        #region Cac Ham Ghi Log

        public static void WriteError(string error)
        {
            //try
            //{
                FileInfo file = new FileInfo("/error.txt");
                if (!file.Exists)
                {
                    System.IO.File.Create("/error.txt");
                }

                StreamWriter sw = file.AppendText();
                sw.WriteLine(error);
                sw.Close();
            //}
            //catch (IOException ie)
            //{

            //}

        }

        #endregion

        #region Cac Ham ViewState Compress va DeCompress

        public static byte[] Compress(byte[] data) {
            MemoryStream output = new MemoryStream();
            GZipStream gzip = new GZipStream(output, 
                              CompressionMode.Compress, true);
            gzip.Write(data, 0, data.Length);
            gzip.Close();
            return output.ToArray();
        }

          public static byte[] Decompress(byte[] data) {
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
            GZipStream gzip = new GZipStream(input, 
                              CompressionMode.Decompress, true);
            MemoryStream output = new MemoryStream();
            byte[] buff = new byte[64];
            int read = -1;
            read = gzip.Read(buff, 0, buff.Length);
            while(read > 0) {
              output.Write(buff, 0, read);
              read = gzip.Read(buff, 0, buff.Length);
            }
            gzip.Close();
            return output.ToArray();
          }
        #endregion
    }

    public enum CompressOptions
    {
        GZip,
        Deflate,
        None
    }

    public class WhitespaceFilter : Stream
    {
        private GZipStream _contentGZip;
        private DeflateStream _content_Deflate;
        private Stream _content;
        private CompressOptions _options;

        public WhitespaceFilter(Stream content, CompressOptions options)
        {
            if (options == CompressOptions.GZip)
            {
                this._contentGZip = new GZipStream(content, CompressionMode.Compress);
                this._content = this._contentGZip;
            }
            else if (options == CompressOptions.Deflate)
            {
                this._content_Deflate = new DeflateStream(content, CompressionMode.Compress);
                this._content = this._content_Deflate;
            }
            else
            {
                this._content = content;
            }
            this._options = options;
        }


        public override bool CanRead
        {
            get { return this._content.CanRead; }
        }

        public override bool CanSeek
        {
            get { return this._content.CanSeek; }
        }

        public override bool CanWrite
        {
            get { return this._content.CanWrite; }
        }

        public override void Flush()
        {
            this._content.Flush();
        }

        public override long Length
        {
            get { return this._content.Length; }
        }

        public override long Position
        {
            get
            {
                return this._content.Position;
            }
            set
            {
                this._content.Position = value;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return this._content.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return this._content.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            this._content.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] data = new byte[count + 1];
            Buffer.BlockCopy(buffer, offset, data, 0, count);


            string s = System.Text.Encoding.UTF8.GetString(data);
            s = Regex.Replace(s, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
            s = Regex.Replace(s, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
            s = Regex.Replace(s, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);

            byte[] outdata = System.Text.Encoding.UTF8.GetBytes(s);
            this._content.Write(outdata, 0, outdata.GetLength(0));
        }

    }
}
